反对模板静态多态的一个论点是，接口的绑定通过实例化相应的模板来完成，没有公共接口(类)用来编程。若所有实例化的代码都有效，那么模板就可以工作。若不是，可能会导致难以理解的错误消息，甚至导致有效但意外的行为。

由于这个原因，C++语言设计人员致力于为模板参数显式提供(和检查)接口的能力。这样的接口在C++中称为概念，表示模板参数必须满足一组约束后，才能成功实例化模板。

尽管各路开发者这些年在这个领域做了许多工作，但是概念直到C++17，才成为标准C++的一部分。一些编译器提供了对这种特性的实验性支持，但这些概念可能会成为C++17之后标准的一部分。

\begin{tcolorbox}[colback=webgreen!5!white,colframe=webgreen!75!black]
\hspace*{0.75cm}例如，GCC 7提供了-fconcepts选项。
\end{tcolorbox}

概念可以理解为静态多态的一种“接口”:

\hspace*{\fill} \\ %插入空行
\noindent
\textit{poly/conceptsreq.hpp}
\begin{lstlisting}[style=styleCXX]
#include "coord.hpp"
template<typename T>
concept GeoObj = requires(T x) {
	{ x.draw() } -> void;
	{ x.center_of_gravity() } -> Coord;
	...
};
\end{lstlisting}

这里，使用关键字概念来定义概念GeoObj，约束类型具有可调用成员draw()和center\_of\_gravity()，并具有适当的结果类型。

现在，可以重写一些示例模板，以包含一个require子句，用GeoObj概念约束模板参数:

\hspace*{\fill} \\ %插入空行
\noindent
\textit{poly/conceptspoly.hpp}
\begin{lstlisting}[style=styleCXX]
#include "conceptsreq.hpp"
#include <vector>

// draw any GeoObj
template<typename T>
requires GeoObj<T>
void myDraw (T const& obj)
{
	obj.draw(); // call draw() according to type of object
}

// compute distance of center of gravity between two GeoObjs
template<typename T1, typename T2>
requires GeoObj<T1> && GeoObj<T2>
Coord distance (T1 const& x1, T2 const& x2)
{
	Coord c = x1.center_of_gravity() - x2.center_of_gravity();
	return c.abs(); // return coordinates as absolute values
}

// draw homogeneous collection of GeoObjs
template<typename T>
requires GeoObj<T>
void drawElems (std::vector<T> const& elems)
{
	for (std::size_type i=0; i<elems.size(); ++i) {
		elems[i].draw(); // call draw() according to type of element
	}
}
\end{lstlisting}

对于能够参与(静态)多态行为的类型来说，这种方法属于非侵入:

\begin{lstlisting}[style=styleCXX]
// concrete geometric object class Circle
// - not derived from any class or implementing any interface
class Circle {
	public:
	void draw() const;
	Coord center_of_gravity() const;
	...
};
\end{lstlisting}

这些类型仍然定义在没有特定基类或需求子句的情况下，并且仍然可以是基本类型，或源自独立框架的类型。

附录E包含了对C++概念的更详细的讨论，这些概念将在下一个C++标准中出现。



















